﻿// <copyright file="ValidationResultsExtension.cs" company="City of Portland, BES-ASM">
// </copyright>
// <summary>ValidationResultsExtension class extension</summary>

namespace BESASM.EMGAATS.BusinessClasses
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using FluentValidation.Results;

  /// <summary>
  /// Extension methods for validation results.
  /// </summary>
  public static class ValidationResultsExtension
  {
    /// <summary>
    /// Determines if the validation results contain errors.
    /// </summary>
    /// <param name="results">The results to examine.</param>
    /// <returns>A value indicating if the results contain errors.</returns>
    public static bool HasErrors(this ValidationResult results)
    {
      return results.Errors.FirstOrDefault(failure => failure.IsError()) != null;
    }

    /// <summary>
    /// Determines if the validation results contain warnings.
    /// </summary>
    /// <param name="results">The results to examine.</param>
    /// <returns>A value indicating if the results contain warnings.</returns>
    public static bool HasWarnings(this ValidationResult results)
    {
      return results.Errors.FirstOrDefault(failure => failure.IsWarning()) != null;
    }

    /// <summary>
    /// Determines if the validation results contain info messages.
    /// </summary>
    /// <param name="results">The results to examine.</param>
    /// <returns>A value indicating if the results contain info messages.</returns>
    public static bool HasInfo(this ValidationResult results)
    {
      return results.Errors.FirstOrDefault(failure => failure.IsInfo()) != null;
    }

    /// <summary>
    /// Gets the number of errors in this validation result.
    /// </summary>
    /// <param name="results">The validation results.</param>
    /// <returns>The number of errors in the results.</returns>
    public static int ErrorCount(this ValidationResult results)
    {
      return results.Errors.Count(failure => failure.IsError());
    }

    /// <summary>
    /// Gets the number of warnings in this validation result.
    /// </summary>
    /// <param name="results">The validation results.</param>
    /// <returns>The number of warnings in the results.</returns>
    public static int WarningCount(this ValidationResult results)
    {
      return results.Errors.Count(failure => failure.IsWarning());
    }

    /// <summary>
    /// Gets the number of info messages in this validation result.
    /// </summary>
    /// <param name="results">The validation results.</param>
    /// <returns>The number of info messages in the results.</returns>
    public static int InfoCount(this ValidationResult results)
    {
      return results.Errors.Count(failure => failure.IsInfo());
    }

    /// <summary>
    /// Gets the errors in this validation result.
    /// </summary>
    /// <param name="results">The validation results.</param>
    /// <returns>The errors in the validation results.</returns>
    public static IEnumerable<ValidationFailure> GetErrors(this ValidationResult results)
    {
      return results.Errors.Where(failure => failure.IsError());
    }

    /// <summary>
    /// Returns all warnings in this validation result.
    /// </summary>
    /// <param name="results">The validation results.</param>
    /// <returns>The warnings in the validation results.</returns>
    public static IEnumerable<ValidationFailure> GetWarnings(this ValidationResult results)
    {
      return results.Errors.Where(failure => failure.IsWarning());
    }

    /// <summary>
    /// Returns all info messages contained in this validation result.
    /// </summary>
    /// <param name="results">The validation results.</param>
    /// <returns>The info messages in the validation results.</returns>
    public static IEnumerable<ValidationFailure> GetInfo(this ValidationResult results)
    {
      return results.Errors.Where(failure => failure.IsInfo());
    }

    /// <summary>
    /// Gets the error level for this validation failure.
    /// </summary>
    /// <param name="failure">The validation failure.</param>
    /// <returns>The error level for this validation failure.</returns>
    public static ErrorLevel Level(this ValidationFailure failure)
    {
      ValidationState state = failure.CustomState as ValidationState;
      if (state != null)
      {
        return state.Level;
      }
      else
      {
        return ErrorLevel.Error;
      }
    }

    /// <summary>
    /// Gets a value indicating whether this validation failure is an error.
    /// </summary>
    /// <param name="failure">The validation failure.</param>
    /// <returns>A value indicating whether this validation failure is an error.</returns>
    public static bool IsError(this ValidationFailure failure)
    {
      return failure.Level() == ErrorLevel.Error;
    }

    /// <summary>
    /// Gets a value indicating whether this validation failure is a warning.
    /// </summary>
    /// <param name="failure">The validation failure.</param>
    /// <returns>A value indicating whether this validation failure is a warning.</returns>
    public static bool IsWarning(this ValidationFailure failure)
    {
      return failure.Level() == ErrorLevel.Warning;
    }

    /// <summary>
    /// Gets a value indicating whether this validation failure is an info message.
    /// </summary>
    /// <param name="failure">The validation failure.</param>
    /// <returns>A value indicating whether this validation failure is an info message.</returns>
    public static bool IsInfo(this ValidationFailure failure)
    {
      return failure.Level() == ErrorLevel.Info;
    }

    /// <summary>
    /// Gets the source object resulting in this validation failure.
    /// </summary>
    /// <param name="failure">The validation failure.</param>
    /// <returns>The source object resulting in this validation failure.</returns>
    public static object SourceObject(this ValidationFailure failure)
    {
      ValidationState state = failure.CustomState as ValidationState;
      if (state != null)
      {
        return state.Object;
      }
      else
      {
        return null;
      }
    }
  }
}
